package it.bambo.tankwars.model;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

/**
 * Andreas Baumgartner: andreas@bambo.it
 */
public class Tank extends Unit {

    public static final int MAX_BULLETS = 5;

    private Color color;

    private int speed = 2;

    private Point towerPosition;
    private double towerDirection;

    private List<Bullet> bullets = new ArrayList<Bullet>();

    public Tank(BattleField battleField, Color color, ControlType controlType, Point point) {
        super(battleField, new Rectangle(point.x, point.y, 16, 16));
        this.color = color;
        this.controlType = controlType;

        updateTowerPosition();
    }

    @Override
    public BufferedImage getImage() {
        this.image = new BufferedImage((int) (rect.width * 1.2), (int) (rect.height * 1.2), BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = image.createGraphics();
        graphics.setColor(color);

        graphics.drawLine(rect.width / 2, rect.height / 2, towerPosition.x, towerPosition.y);
        graphics.drawRect((int) (rect.width * 0.1), (int) (rect.height * 0.1), (int) (rect.width * 0.66), rect.height);

        return this.image;
    }

    @Override
    public void executeCommand(Command command) {
        if (CommandType.DIRECTION.equals(command.getType())) {
            updatePosition(command);
        } else if (CommandType.TOWER_CHANGE.equals(command.getType())) {
            updateTowerDirection(command.getValue());
            updateTowerPosition();
        } else if (CommandType.TOWER_ABSOLUT.equals(command.getType())) {
            towerDirection = command.getValue();
            updateTowerPosition();
        } else if (CommandType.FIRE.equals(command.getType())) {
            final Tank tank = this;
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    if (bullets.size() < MAX_BULLETS) {
                        new Bullet(battleField, tank,
                                new Point(towerPosition.x + rect.x, towerPosition.y + rect.y));
                    }
                }
            });
        }
    }

    private void updatePosition(Command command) {
        Rectangle rectangle = (Rectangle) rect.clone();
        if (command.getValue() <= 22.5 || command.getValue() >= 337.5) {
            rectangle.y = rect.y - speed;
        } else if (command.getValue() > 22.5 && command.getValue() <= 67.5) {
            rectangle.y = rect.y - speed;
            rectangle.x = rect.x + speed;
        } else if (command.getValue() > 67.5 && command.getValue() <= 112.5) {
            rectangle.x = rect.x + speed;
        } else if (command.getValue() > 112.5 && command.getValue() <= 157.5) {
            rectangle.x = rect.x + speed;
            rectangle.y = rect.y + speed;
        } else if (command.getValue() > 157.5 && command.getValue() <= 202.5) {
            rectangle.y = rect.y + speed;
        } else if (command.getValue() > 202.5 && command.getValue() <= 247.5) {
            rectangle.y = rect.y + speed;
            rectangle.x = rect.x - speed;
        } else if (command.getValue() > 247.5 && command.getValue() <= 292.5) {
            rectangle.x = rect.x - speed;
        } else if (command.getValue() > 292.5 && command.getValue() <= 337.5) {
            rectangle.x = rect.x - speed;
            rectangle.y = rect.y - speed;
        }
        if (battleField.intersectsObstacle(this, rectangle) == null &&
                battleField.getField().contains(rectangle)) {
            rect = rectangle;
        }
    }

    private void updateTowerDirection(double value) {
        towerDirection = towerDirection + value;
        if (towerDirection < 0) {
            towerDirection = 360 + towerDirection;
        } else if (towerDirection >= 360) {
            towerDirection = towerDirection - 360;
        }
    }

    private void updateTowerPosition() {
        towerPosition = new Point((int) ((rect.width) * Math.cos(Math.toRadians(towerDirection))) + rect.width / 2,
                (int) ((rect.height) * Math.sin(Math.toRadians(towerDirection))) + rect.height / 2);
    }

    public List<Bullet> getBullets() {
        return bullets;
    }

    public double getTowerDirection() {
        return towerDirection;
    }
}
